package com.example.gobang.game;


import com.example.gobang.JavaGobangApplication;
import com.example.gobang.model.User;
import com.example.gobang.model.UserMapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.UUID;

@Data
public class Room {
    private String roomId;

    private User user1;
    private User user2;

    private int whiteUser;

    private ObjectMapper objectMapper = new ObjectMapper();

    private static final int MAX_ROW = 15;
    private static final int MAX_COL = 15;

    private int board[][] = new int[MAX_ROW][MAX_COL];



    private OnlineUserManager onlineUserManager;


    private RoomManager roomManager;

    private UserMapper userMapper;

    public Room() {
        roomId = UUID.randomUUID().toString();

        onlineUserManager = JavaGobangApplication.context.getBean(OnlineUserManager.class);
        roomManager = JavaGobangApplication.context.getBean(RoomManager.class);

        userMapper = JavaGobangApplication.context.getBean(UserMapper.class);
    }

    public void putChess(String reqJson) throws IOException {

        GameRequest request = objectMapper.readValue(reqJson , GameRequest.class);
        GameResponse response = new GameResponse();

        int chess = request.getUserId() == user1.getUserId() ? 1 : 2;
        int row = request.getRow();
        int col = request.getCol();
        if(board[row][col] != 0) {
            System.out.println("当前位置 (" + row +", "+ col +")已经有子了!");
            return;
        }
        board[row][col] = chess;
        printBoard();


        int winner = checkWinner(row, col, chess);

        response.setMessage("putChess");
        response.setUserId(request.getUserId());
        response.setRow(row);
        response.setCol(col);
        response.setWinner(winner);

        WebSocketSession session1 = onlineUserManager.getFromGameRoom(user1.getUserId());
        WebSocketSession session2 = onlineUserManager.getFromGameRoom(user2.getUserId());

        if(session1 == null){
            response.setWinner(user2.getUserId());
            System.out.println("玩家1掉线");
        }
        if(session2 == null){
            response.setWinner(user1.getUserId());
            System.out.println("玩家2掉线");
        }

        String respJson = objectMapper.writeValueAsString(response);
        if(session1 != null) {
            session1.sendMessage(new TextMessage(respJson));
        }
        if(session2 != null) {
            session2.sendMessage(new TextMessage(respJson));
        }

        if(response.getWinner() != 0) {
            System.out.println("游戏结束! roomId =" + roomId +"获胜者为" + response.getWinner() );
            int winUserId = response.getWinner();
            int loseUserId = response.getWinner() == user1.getUserId() ? user2.getUserId() : user1.getUserId();
            userMapper.userWin(winUserId);
            userMapper.userLose(loseUserId);
            onlineUserManager.exitGameRoom(winUserId);
            onlineUserManager.exitGameRoom(loseUserId);
            roomManager.remove(roomId,user1.getUserId(),user2.getUserId());


        }


    }

    private void printBoard() {
        System.out.println("[打印棋盘信息]");
        System.out.println("====================================");
        for (int r = 0; r < MAX_ROW; r++) {
            for (int c = 0; c < MAX_COL; c++) {
                System.out.print(board[r][c] + " ");
            }
            System.out.println();

        }
        System.out.println("====================================");


    }

    private int checkWinner(int row, int col, int chess) {

        for (int c = col - 4; c <= col ; c++) {
            try {
                if (board[row][c] == chess
                        && board[row][c + 1] == chess
                        && board[row][c + 2] == chess
                        && board[row][c + 3] == chess
                        && board[row][c + 4] == chess) {
                    return chess == 1 ? user1.getUserId() : user2.getUserId();
                }
            } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }
            for (int r = row - 4; r <= row ; r++) {
                try {
                    if (board[r][col] == chess
                            && board[r + 1][col] == chess
                            && board[r + 2][col] == chess
                            && board[r + 3][col] == chess
                            && board[r + 4][col] == chess) {
                        return chess == 1 ? user1.getUserId() : user2.getUserId();
                    }
                } catch (ArrayIndexOutOfBoundsException e) {
                    continue;
                }
            }
                for ( int r = row - 4, c = col - 4; r <= row  && c <= col; r++ , c++) {
                    try {
                        if(board[r][c] == chess
                                && board[r + 1][c + 1] == chess
                                && board[r + 2][c + 2] == chess
                                && board[r + 3][c + 3] == chess
                                && board[r + 4][c + 4] == chess) {
                            return chess == 1 ? user1.getUserId() : user2.getUserId();
                        }
                    }catch (ArrayIndexOutOfBoundsException e) {
                        continue;
                    }

                }
                for (int r = row - 4, c = col + 4; r <= row && c >= col; r++, c--) {
                     try {
                        if (board[r][c] == chess
                        && board[r + 1][c - 1] == chess
                        && board[r + 2][c - 2] == chess
                        && board[r + 3][c - 3] == chess
                        && board[r + 4][c - 4] == chess) {
                      return chess == 1 ? user1.getUserId() : user2.getUserId();
                  }
                } catch (ArrayIndexOutOfBoundsException e) {
                continue;
            }
        }

        return 0;
    }

    public static void main(String[] args) {
        Room room = new Room();
        System.out.println(room.roomId);
    }
}
